package com.kevin.pro;

import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedDeque;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.locks.LockSupport;

/**
 * 使用队列实现的公平锁
 *
 * @author Kevin Liu
 * @since 1.0.0
 */
public class FiFoLock implements Lock{

    private final AtomicBoolean locked = new AtomicBoolean(false);

    private final Queue<Thread> waiters = new ConcurrentLinkedDeque<>();


    @Override
    public void lock() {
        //判断是否被其他前程的中断标志
        boolean wasInterrupted = false;
        Thread current = Thread.currentThread();
        waiters.add(current);
        //只有队首的可以获取锁
        while(waiters.peek() != current || !locked.compareAndSet(false,true)) {
            LockSupport.park(this);
            if(Thread.interrupted()) {
                wasInterrupted = true;
            }
         }
        waiters.remove();
        if(wasInterrupted) {
            current.interrupt();
        }
    }

    @Override
    public void unlock() {
        locked.set(false);
        LockSupport.unpark(waiters.peek());
    }
}

